#!/bin/bash

# Requirements:
# - DBD-ODBC in upper directory
# - PWD* files
# - gawk, lcov packages
# - fixdoxyres, vg_test, classifier commands
# - freetds_autobuild.sh and suppressions.supp configurations

export PATH="/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/usr/lib/jre/bin:$HOME/bin:$HOME/install/bin"

. $HOME/.bashrc

# do not use ccache, not work well with profile informations
export PATH="/usr/kerberos/bin:/usr/local/bin:$HOME/bin:$HOME/install/bin:/bin:/usr/bin:/usr/X11R6/bin"

GROUPDIR=/home/groups/f/fr/freetds/htdocs
# directory to compile
FTDSDIR=freetds91
# output directory on server
OUTDIR=out
# additional flags for Autogen (current version)
#FLAGS_ADD=--enable-developing
FLAGS_ADD="$TDS_AUTO_CONFIG"
WORKDIR=ftds_comp

upload()
{
	local dir=$1
	mkdir -p "$HOME/cpp/freetds/html/$1"
	rm -rf "$HOME/cpp/freetds/html/$1"
	mkdir -p "$HOME/cpp/freetds/html/$1"
	shift
	cp -r $@ "$HOME/cpp/freetds/html/$dir"
#	tar zcf - $2 | ssh -p 443 freddy77@shell-ssh.sourceforge.net "cd $GROUPDIR/$1 && rm -rf * && { tar zxf -; find . -type d -print0 | xargs -0 chmod 2775; find . -type f -print0 | xargs -0 chmod 0664; }"
}

upload_file()
{
	mkdir -p `dirname "$HOME/cpp/freetds/html/$1"`
	cp $2 "$HOME/cpp/freetds/html/$1"
#	ssh -p 443 freddy77@shell-ssh.sourceforge.net "cd $GROUPDIR && cat - > $1 && chmod 0664 $1" < $2
}

cov()
{
	covfile="${1}.cov_info"
	shift
	./misc/grabcov -o "$covfile" -- "$@"
}

del_coverage()
{
	test "$covfile" = "" || rm -f "$covfile"
	covfile=
}

handle_exit()
{
	echo Exiting...
	rm -rf $WORKDIR
}

set_pwd_file()
{
	rm -f PWD
	cp -f "$1" PWD
	tUID=`grep '^UID=' < PWD | sed 's,^....,,'`
	tPWD=`grep '^PWD=' < PWD | sed 's,^....,,'`
	tSRV=`grep '^SRV=' < PWD | sed 's,^....,,'`
	tDB=`grep '^DB=' < PWD | sed 's,^...,,'`
}

init_log()
{
	rm -rf logs
	mkdir logs
	touch logs/log.txt
	cd ..
	ln -f $WORKDIR/logs/log.txt ${WORKDIR}_log.txt
	exec &> ${WORKDIR}_out.txt
	cd $WORKDIR
}

rm -f ~/freetds.log /tmp/sql.log

COMMIT=''
while test $# -gt 0; do
	param="$1"
	shift
	case "$param" in
	--version)
		OUTDIR=out$1
		FTDSDIR=freetds$1
		WORKDIR=ftds_comp$1
		shift
		;;
	--commit)
		COMMIT="$1"
		shift
		;;
	--help)
		echo "Syntax: freetds_autobuild [--version VERSION] [--commit COMMIT] [--help]"
		exit 1
		;;
	*)
		echo "Option $param not supported!" 1>&2
		exit 1
		;;
	esac
done

WORKDIR="$HOME/ftdstmp/$WORKDIR"

set -e
trap 'echo Error at line $LINENO' ERR

DOMAIN_UID=
DOMAIN_PWD=
MSSQL_PORT=
MSSQL_INSTANCE=
if test -r "$HOME/freetds_autobuild.sh"; then
	. "$HOME/freetds_autobuild.sh"
fi

cd $HOME/cpp/freetds/$FTDSDIR
cd ..
ROOT=$PWD
rm -rf $WORKDIR
trap handle_exit EXIT
test -d $FTDSDIR
mkdir $WORKDIR
cd $FTDSDIR
if test "$COMMIT" = ""; then
	REV="$(git rev-parse HEAD)"
else
	REV="$COMMIT"
fi
git archive $REV | tar -C $WORKDIR -xvf -
cp doc/userguide_desc.xml $WORKDIR/doc/
cd $WORKDIR
echo "$REV" > git_revision
if test "$(uname -m)" = "x86_64"; then
	cp $ROOT/DBD-ODBC-1.52.tar.gz .
else
	cp $ROOT/DBD-ODBC-1.52.tar.gz .
fi
cp $ROOT/php5.2-latest.tar.bz2 .

# -U_FORTIFY_SOURCE is to avoid a bug in Valgrind detecting memmove as memcpy
LDFLAGS='-lgcov' CFLAGS='-O2 -pipe -g -U_FORTIFY_SOURCE -fprofile-arcs -ftest-coverage' sh autogen.sh --enable-extra-checks --prefix=$HOME/install --with-odbc-nodm=/usr --enable-krb5 $FLAGS_ADD

# compile, test with mssql server
set_pwd_file $ROOT/PWD.mssql2005
export LD_LIBRARY_PATH=$PWD/src/odbc/.libs/
init_log
./misc/test-auto.sh --no-test  >> logs/log.txt

# replicate
cd ..
BASE="$(basename $WORKDIR)"
cp -rl $BASE $BASE.tmp
mv $BASE.tmp $BASE
cd $BASE
mv $BASE.tmp test1
cp -rl test1 test2
cp -rl test1 test3
cp -rl test1 test4
cp -rl test1 test5

grab_logs() {
	find -path '*/unittests/*.log' -type f | sort | while read fn; do
		if test -x "${fn%.log}"; then
			 cat "$fn"
		fi
	done >> logs/log.txt
}

create_test_db() {
	# create test database, ignore failure, possibly already created
	echo "Creating database..."
	echo -e 'CREATE DATABASE freetds_test\ngo\nbye\n' | ./src/apps/tsql -S $tSRV -U "$tUID" -P "$tPWD" || true
}

generic_test() {
	trap 'echo Error $? at line $LINENO' ERR
	local dir="$1" pwd_file="$2"
	cd "$dir"
	WORKDIR=$PWD
	set_pwd_file $ROOT/$pwd_file
	init_log
	create_test_db
	./misc/test-auto.sh --no-build >> logs/log.txt
	grab_logs
	cd logs
	../misc/online.pl < log.txt
	rm log.txt
	find -name test\*.txt -delete
	upload "$OUTDIR/$dir" '*.html' '*.txt'
	cd ..
}

test1() {
	trap 'echo Error $? at line $LINENO' ERR
cd test1
WORKDIR=$PWD
create_test_db
./misc/test-auto.sh --no-build --no-header >> logs/log.txt
grab_logs

if test \( "$OUTDIR" = "out" -o "$OUTDIR" = "out99" \) -a -r doc/doxy.log; then
	./misc/fixdoxyres < doc/doxy.log > doc/doxy.html
	upload_file "doxy.html" "doc/doxy.html"
	if test -d doc/reference; then
		(cd doc/reference; upload doxy '*')
	fi 
fi

# save logs for debug
rm -f ../log_tds.txt
ln logs/log.txt ../log_tds.txt

# test Perl
RES=0
# setting LANG avoid strange characters
LANG=en_US cov perl ./misc/test-other.sh --perl-only --verbose >> logs/log.txt || RES=$?
if test $RES != 0; then
	echo "Perl test failed"
	del_coverage
fi

./misc/test-other.sh --php-only >> logs/log.txt || true

# upload our test results
cd logs
perl -pe "\$_ = '' if \$_ =~ /^2:.*content model is mixed but does not allow #PCDATA everywhere/" < log.txt | ../misc/online.pl
rm log.txt
find -name test\*.txt -delete
upload "$OUTDIR/test" '*.html' '*.txt'
cd ..

# test connection using named port
# using tsql directly with grep do not update coverage informations
echo -e 'select @@version\ngo\nbye' | TDSPORT=ms-sql-s cov named_port ./src/apps/tsql -S $tSRV -U "$tUID" -P "$tPWD" > out.txt || true
if grep -q 'Microsoft Corporation' out.txt; then
	echo "named port ok"
else
	echo "named port failed!"
	del_coverage
fi
rm -f out.txt

# test dump to file
# using tsql directly with grep do not update coverage informations
echo -e 'select @@version\ngo\nbye' | TDSDUMP=dump.txt cov dump ./src/apps/tsql -S $tSRV -U "$tUID" -P "$tPWD" > out.txt || true
res=ok
grep -q 'Microsoft Corporation' out.txt || res=ko
grep -q 'Starting log file for FreeTDS' dump.txt || res=ko
grep -q 'tds_process_login_tokens() returning' dump.txt || res=ko
grep -q 'Changed query state from' dump.txt || res=ko
if test $res = ok; then
	echo "dump test ok"
else
	echo "dump test failed!"
	del_coverage
fi
rm -f out.txt dump.txt

#
# test domain password and TDSPORT with service name
if test "$DOMAIN_UID" != ""; then
	# using tsql directly with grep do not update coverage informations
	echo -e 'select @@version\ngo\nbye' | TDSDUMP=stdout cov domain ./src/apps/tsql -S $tSRV -U "$DOMAIN_UID" -P "$DOMAIN_PWD" > out.txt || true
	if grep -q 'Microsoft Corporation' out.txt; then
		echo "domain password ok"
	else
		echo "domain password failed!"
		del_coverage
	fi
	rm -f out.txt
fi

# test connection forcing port
if test "$MSSQL_PORT" != ""; then
	# using tsql directly with grep do not update coverage informations
	echo -e 'select @@version\ngo\nbye' | cov forced_port ./src/apps/tsql -S "$tSRV:$MSSQL_PORT" -U "$tUID" -P "$tPWD" > out.txt || true
	if grep -q 'Microsoft Corporation' out.txt; then
		echo "override port ok"
	else
		echo "override port failed!"
		del_coverage
	fi
	rm -f out.txt
fi

# test connection using instance name
if test "$MSSQL_INSTANCE" != ""; then
	# using tsql directly with grep do not update coverage informations
	echo -e 'select @@version\ngo\nbye' | cov instance ./src/apps/tsql -S "$tSRV\\$MSSQL_INSTANCE" -U "$tUID" -P "$tPWD" > out.txt || true
	if grep -q 'Microsoft Corporation' out.txt; then
		echo "override instance ok"
	else
		echo "override instance failed!"
		del_coverage
	fi
	rm -f out.txt
fi
}

test_sybase15() {
	# do tests with sybase 15 server
	generic_test test3 PWD.sybase15
}

test_mssql2008() {
	# do tests with mssql 2008
	generic_test test4 PWD.mssql2008
}

test_mssql2000() {
	trap 'echo Error $? at line $LINENO' ERR
	local pid_pool
	cd test2
	./misc/grabcov -o pool.cov_info -- ./src/pool/tdspool msde &> /dev/null &
	pid_pool=$!
	sleep 5
	pid_pool=$(pgrep -P $pid_pool tdspool)
	cd ..
	# do tests with mssql 2000
	generic_test test2 PWD.msde_pool
	kill $pid_pool
}

left=(test1 test_mssql2008 test_mssql2000 test_sybase15)

limit=4
while true; do
	# get job pids
	running=($(jobs -rp))

	# launch another process if necessary
	if [ ${#running[@]} -lt $limit -a ${#left[@]} -gt 0 ]; then
		${left[0]} &
		left=("${left[@]:1}")
	elif [ ${#running[@]} = 0 ]; then
		# we finish all jobs, done
		break
	else
		# wait any process to finish
		wait -n ${running[@]}
	fi
done

# test autodiscovery
set_pwd_file $ROOT/PWD.sybase15
# using tsql directly with grep do not update coverage informations
echo -e 'select @@version\ngo\nbye' | TDSVER=auto cov discovery ./src/apps/tsql -S "$tSRV" -U "$tUID" -P "$tPWD" > out.txt || true
if grep -q 'Adaptive Server Enterprise' out.txt; then
	echo "autodiscovery ok"
else
	echo "autodiscovery failed!"
	del_coverage
fi
rm -f out.txt

# build coverage and upload it
find -name \*.\[ch\] -o -name \*.gperf -o -name \*.cov_info.gz -o -name git_revision | tar cvf ${WORKDIR}.covs.tar -T -

# cleanup
rm -f ~/freetds.log /tmp/sql.log covsave.tgz
rm -rf logs
